package com.wyr.admin.controller;

import com.wyr.common.constants.RedisConstants;
import com.wyr.common.vo.Result;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;

import static jodd.util.ThreadUtil.sleep;

/**
 * mq管理
 *
 * @author wangyiren
 * @version 1.0
 * &#064;title MqController
 * &#064;description
 * &#064;date 2025/03/06 14:37
 */
@Slf4j
@Tag(name = "Redisson管理")
@RestController
@RequestMapping("redisson")
public class RedissonController {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 未加分布式锁-库存扣减
     * 模拟未加分布式锁时的库存扣减情况
     * <p>
     * &#064;description
     *
     * @return: com.wyr.common.vo.Result<?>
     * @author wangyiren
     * &#064;date 2025/4/2 13:49
     */
    @Operation(summary = "未加分布式锁-库存扣减")
    @GetMapping("/unLock/flash_sale")
    public Result<?> unlockFlashSale() {
        int phoneStock = 0;
        try {
            // 3.执行业务逻辑
            String phoneCount = stringRedisTemplate.opsForValue().get("phone_stock");
            if (StringUtils.isBlank(phoneCount) || Integer.parseInt(phoneCount) == 0) {
                stringRedisTemplate.opsForValue().set("phone_stock", String.valueOf(10));
            }
            phoneStock = Integer.parseInt(Objects.requireNonNull(phoneCount));
            if (phoneStock > 0) {
                phoneStock--;
                stringRedisTemplate.opsForValue().set("phone_stock", String.valueOf(phoneStock));
                System.out.println("库存-1后，库存剩余：" + phoneStock);
            } else {
                System.out.println("库存不足");
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        }
        return Result.ok("当前库存：" + phoneStock);
    }

    /**
     * 分布式锁-库存扣减
     * <p>
     * &#064;description
     *
     * @return: com.wyr.common.vo.Result<?>
     * @author wangyiren
     * &#064;date 2025/4/2 13:48
     */
    @Operation(summary = "分布式锁-库存扣减")
    @GetMapping("/lock/flash_sale")
    public Result<?> flashSale() {
        // 1.获取锁对象
        RLock lock = redissonClient.getLock("phone_lock");
        // 2.加锁  默认30秒
        lock.lock();

        int phoneStock = 0;
        try {
            // 3.执行业务逻辑
            String phoneCount = stringRedisTemplate.opsForValue().get("phone_stock");
            if (StringUtils.isBlank(phoneCount) || Integer.parseInt(phoneCount) == 0) {
                stringRedisTemplate.opsForValue().set("phone_stock", String.valueOf(10));
            }
            phoneStock = Integer.parseInt(Objects.requireNonNull(phoneCount));
            if (phoneStock > 0) {
                phoneStock--;
                stringRedisTemplate.opsForValue().set("phone_stock", String.valueOf(phoneStock));
                System.out.println("库存-1后，库存剩余：" + phoneStock);
            } else {
                System.out.println("库存不足");
            }
        } catch (Exception e) {
            log.error(e.getMessage());
        } finally {
            // 4.释放锁
            lock.unlock();
        }
        return Result.ok("当前库存：" + phoneStock);
    }

    /**
     * 分布式锁-样列
     *
     * @param traceId
     * @param data    &#064;description
     * @return: com.wyr.common.vo.Result<?>
     * @author wangyiren
     * &#064;date 2025/3/21 09:55
     */
    @Operation(summary = "分布式锁-样列")
    @Parameters({
            @Parameter(name = "traceId", description = "traceId", required = true, in = ParameterIn.QUERY),
            @Parameter(name = "data", description = "data", required = true, in = ParameterIn.QUERY),
    })
    @GetMapping("lock")
    public Result<?> lock(String traceId, String data) {
        //加锁
        RLock lock = redissonClient.getLock(RedisConstants.RedisKey.LOCK_GET_TOKEN + traceId);
        // 加锁（阻塞等待），默认30秒
        lock.lock();
        try {
            System.out.println(data);
            //模拟耗时
            sleep(3000);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            // 释放锁
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
        return Result.ok();
    }


}
